package com.boyon.system.service;

import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.boyon.common.domain.UserSession;
import com.boyon.common.exection.BusinessException;
import com.boyon.common.status.AccountEnmu;
import com.boyon.common.status.StatusType;
import com.boyon.common.tools.Md5Tool;
import com.boyon.common.tools.ObjectTool;
import com.boyon.common.tools.RsaTool;
import com.boyon.hbm.criteria.OperationType;
import com.boyon.hbm.criteria.Param;
import com.boyon.hbm.criteria.Query;
import com.boyon.service.AbstractService;
import com.boyon.system.entity.Account;
import com.boyon.system.entity.AccountRelation;

/**
 * ClassName:AccountService <br/>
 * Function: 系统账号管理业务实现类.继承AbstractService <br/>
 * Date: 2018年3月13日 下午4:45:52 <br/>
 * 
 * @author sunshulin
 * @version
 * @since JDK 1.8
 * @see
 */
@Service
public class AccountService extends AbstractService {

	@Autowired
	private VerificationService verificationService;
	@Value("${rsa.primity.key}")
	private String rsaPrimityKey;
	@Value("${account.default.pass}")
	private String defaultPass;

	/**
	 * 
	 * createAccount:创建账号处理方法 <br/>
	 * 
	 * @author sunshulin
	 * @param logRecord
	 * @param account
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long createAccount(Account account, AccountEnmu accountEnmu,
			Long relationId) {
		Account entity = queryByAccount(account.getAccount());
		if (entity != null) {
			throw BusinessException.builder(0, "用户账号已存在");
		}
		account.setPass(Md5Tool.MD5(defaultPass));
		account.setCreateTime(new Date());
		account.setUpdateTime(new Date());
		account.setStatus(StatusType.start.getStatus());
		if (AccountEnmu.system == accountEnmu) {
			account.setRelationType(AccountEnmu.system.getVal());
		} else if (AccountEnmu.agent == accountEnmu) {
			// 代理商账号,查询代理商账号信息
			account.setRelationType(AccountEnmu.agent.getVal());
		}
		generalDao.saveOrUpdate(account);
		if (AccountEnmu.agent == accountEnmu) {
			AccountRelation accountRelation = new AccountRelation();
			accountRelation.setAccountId(account.getAccountId());
			accountRelation.setRelationId(relationId);
			generalDao.saveOrUpdate(accountRelation);
		}
		return account.getAccountId();
	}

	/**
	 * 
	 * deleteAccount:删除账号. <br/>
	 * 
	 * @author sunshulin
	 * @param accountId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long deleteAccount(Long accountId) {
		Account account = findByAccountId(accountId);
		account.setStatus(StatusType.del.getStatus());
		generalDao.saveOrUpdate(account);
		return account.getAccountId();
	}

	/**
	 * 
	 * enableAccount:账号启用禁用. <br/>
	 * 
	 * @author sunshulin
	 * @param accountId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long enableAccount(Long accountId) {
		Account account = findByAccountId(accountId);
		validatorAccountInfo(account);
		Integer status = null;
		if (StatusType.start.getStatus() == account.getStatus()) {
			status = StatusType.stop.getStatus();
		} else if (StatusType.stop.getStatus() == account.getStatus()) {
			status = StatusType.start.getStatus();
		} else {
			throw BusinessException.builder(0, "状态不可用");
		}
		account.setStatus(status);
		generalDao.saveOrUpdate(account);
		return account.getAccountId();
	}

	/**
	 * 
	 * resetPassword:重置密码业务处理方法. <br/>
	 * 
	 * @author sunshulin
	 * @param account
	 * @since JDK 1.8
	 */
	@Transactional
	public Long resetPassword(Account account) {
		Account entity = generalDao.get(Account.class, account.getAccountId());
		validatorAccount(entity);
		entity.setPass(Md5Tool.MD5(defaultPass));
		generalDao.saveOrUpdate(entity);
		return entity.getAccountId();
	}

	/**
	 * 
	 * modifyPassword:修改密码. <br/>
	 * 
	 * @author sunshulin
	 * @param accountId
	 * @since JDK 1.8
	 */
	@Transactional
	public Long modifyPassword(Account account) {
		Account entity = generalDao.get(Account.class, account.getAccountId());
		validatorAccount(entity);
		entity.setPass(Md5Tool.MD5(account.getPass()));
		generalDao.saveOrUpdate(entity);
		return entity.getAccountId();
	}

	/**
	 * 
	 * login:登录. <br/>
	 * 
	 * @author sunshulin
	 * @param account
	 * @param sessionId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional
	public Long login(Account account, String sessionId) {
		Account entity = null;
		try {
			account.setAccount(new String(RsaTool.decryptByPrivateKey(
					RsaTool.decryptBASE64(account.getAccount()),
					rsaPrimityKey)));
			account.setPass(new String(RsaTool.decryptByPrivateKey(
					RsaTool.decryptBASE64(account.getPass()), rsaPrimityKey)));
			entity = queryByAccount(account.getAccount());
			verificationService.validator(sessionId, account.getCode());
			if (entity.getStatus() != StatusType.start.getStatus()) {
				throw BusinessException.builder(0, "账号已停用");
			}
			if (!entity.getPass().endsWith(Md5Tool.MD5(account.getPass()))) {
				throw BusinessException.builder(0, "密码错误");
			}
		} catch (Exception e) {
			throw BusinessException.builder(0, e);
		} finally {
			if (ObjectTool.isNotNull(entity)) {
				entity.setLastLoginTime(new Date());
				generalDao.saveOrUpdate(entity);
			}
		}
		return ObjectTool.isNotNull(entity) ? entity.getAccountId() : null;
	}

	/**
	 * 
	 * queryByAccount:查询账号. <br/>
	 * 
	 * @author sunshulin
	 * @param logRecord
	 * @param account
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public Account queryByAccount(String account) {
		Query query = new Query();
		query.addParam(new Param<String>("account", OperationType.eq, account));
		query.addParam(new Param<Integer>("status", OperationType.nq, -1));
		Account entity = generalDao.sign(Account.class, query);
		return entity;
	}

	/**
	 * 
	 * query:查询账号列表 <br/>
	 * 
	 * @author sunshulin
	 * @param query
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public List<Account> query(Query query) {
		List<Account> list = generalDao.query(Account.class, query);
		return list;
	}

	/**
	 * 
	 * findByAccountId:查找账号 <br/>
	 * 
	 * @author sunshulin
	 * @param accountId
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public Account findByAccountId(Long accountId) {
		return generalDao.get(Account.class, accountId);
	}

	/**
	 * 
	 * validatorAccountInfo:验证账号基本信息. <br/>
	 * 
	 * @author sunshulin
	 * @param entity
	 * @since JDK 1.8
	 */
	public void validatorAccountInfo(Account entity) {
		if (entity == null) {
			throw BusinessException.builder(0, "账号不存在");
		}
		if (entity.getStatus() == StatusType.del.getStatus()) {
			throw BusinessException.builder(0, "账号已删除");
		}
	}

	/**
	 * 
	 * validatorAccount:账号数据基础验证,验证是否存在,是否已删除. <br/>
	 * 
	 * @author sunshulin
	 * @param entity
	 * @since JDK 1.8
	 */
	public void validatorAccount(Account entity) {
		validatorAccountInfo(entity);
		if (entity.getStatus() == StatusType.stop.getStatus()) {
			throw BusinessException.builder(0, "账号已停用");
		}
	}

	/**
	 * 
	 * createUserSession:创建登录用户session信息. <br/>
	 * 
	 * @author sunshulin
	 * @param account
	 * @return
	 * @since JDK 1.8
	 */
	@Transactional(readOnly = true)
	public UserSession createUserSession(Account account) {
		UserSession userSession = new UserSession();
		ObjectTool.copy(account, userSession, new String[] { "pass" });
		if (account.getRelationType().equals(AccountEnmu.agent.getVal())) {
			AccountRelation accountRelation = generalDao
					.get(AccountRelation.class, account.getAccountId());
			userSession.setRelationId(accountRelation.getRelationId());
			userSession.setQueryPath(accountRelation.getQueryPath());
		}
		return userSession;
	}

}
